<?php

namespace app\api\controller;

use think\Controller;
use think\Db;
use think\Exception;
use think\Queue;
use think\facade\Hook;
use think\facade\Config;

/**
 * 推送任务到队列类
 * Class Task
 * @package app\api\controller
 */
class Task extends Controller
{
	public function lookList(){
		$list = $this->checkRedis();
		halt($list);
	}
	/**
	 * 定时任务执行入口
	 * @return mixed
	 */
	public function index($id = "", $kk = "")
	{
		//测试的时候从新更新队列
		if ($kk) {
			Db::name('mission')->where('mission_id', $id)->update(['mission_queues' => 0]);
		}

		//测试的时候传入的id
		if ($id) {
			$where['mission_id'] = $id;
		}
		$where['mission_state'] = 1;//0未启动1进行中
		$where['mission_type'] = 0;//0不需要补单 1需要补单 2 失败 3 支付中
		//$where['mission_queues'] = 0;//0未加入列队 1提交列队中 2提交列队失败 3列队处理成功 4列队处理失败
		$where["mission_del"] = 0;

		$missionlist = Db::name('mission')
			->where($where)
			->field("mission_id,mission_uid,mission_cid,mission_pay_id,mission_pay_time,mission_current_state,mission_region_id")
			->order('mission_pay_time ASC')
			//->fetchSql(1)
			->select();
		//halt($missionlist);
		if (empty($missionlist)) {
			return "没有可以执行的计划" . PHP_EOL;exit();
		}
		unset($where);
		foreach ($missionlist as $key => $v) {
			//先取出一个账单
			$plan = Db::name('plan')
				->where(['plan_mid' => $v['mission_id'], 'plan_state' => 0])
				->order('plan_pay_time ASC')
				->find();
			//dump($plan);
			if (empty($plan)) {
				echo '计划不存在 [' . $v['mission_id'] . ']<br/>';
				continue;
			}

			$card = Db::name('user_card')->where('card_id', $v['mission_cid'])->where('card_type', 1)->find();
			if (empty($card)) {
				echo '计划 [' . $v['mission_id'] . '] 银行卡不存在<br/>';
				continue;
			}

			$payment = Db::name('payment')
				->where('payment_id', $v['mission_pay_id'])
				->field("payment_id,payment_controller")
				->find();
			if (empty($payment)) {
				echo '计划 [' . $v['mission_id'] . '] 通道不存在<br/>';
				continue;
			}
			$res = $this->jhqueues($v, $plan, $payment, $v['mission_id'] . '-' . $plan['plan_id']);
			echo ($res);
		}
	}

	/**
	 * 进入队列排队
	 * 扣款还款项目队列
	 *
	 * @param string $mission
	 * @param string $plan
	 * @param string $planlist
	 * @param string $payment
	 * @param string $card
	 * @param string $infoId
	 *
	 * @return array
	 */
	protected function jhqueues($mission = '', $plan = '', $payment = '', $infoId = '')
	{
		$jobHandlerClassName = 'app\api\job\Kou';
		if (class_exists($jobHandlerClassName)) {
			//更新提交到队列中
			Db::name('mission')->where('mission_id', $mission['mission_id'])->update(['mission_queues' => 1]);
			// 2.当前任务归属的队列名称，如果为新队列，会自动创建
			$jobQueueName = "jhqueues";


			/****************队列延迟加入***********************/
			$later = rand("30","40")*60;
			if(time()+1200>strtotime(date("Y-m-d 21:30:00"))){
				$later = strtotime(date("Y-m-d 09:10:25",strtotime("+1day")))-time();
			}

			$plan_time = strtotime($mission['mission_pay_time']);
			if ($plan_time > time()) {
				$later = $plan_time - time();
			}
			$isPushed = false;
			$isPushed = $this->checkRedis($mission);//查找redis数据库是否进入
			if(!$isPushed){
				// 3.当前任务所需的业务数据
				$jobData = ['later' => $later, 'strart' => time(), 'mission' => $mission, 'payment' => $payment, 'logid' => $infoId];
				// 4.将该任务推送到消息队列，等待对应的消费者去执行
				Queue::later($later, $jobHandlerClassName, $jobData, $jobQueueName);
				$isPushed = $this->checkRedis($mission);//查找redis数据库是否进入
				/****************队列延迟加入***********************/
			}


			//var_dump($isPushed);


			// database 驱动时，返回值为 1|false  ;   redis 驱动时，返回值为 随机字符串|false
			if ($isPushed !== false) {
				$this->queueLog($payment['payment_controller'], $infoId, $plan['plan_form_no'] . ' MQ排队成功等待处理');
				return json(array('error' => 0, 'msg' => 'MQ排队成功等待处理', 'hid' => $infoId));
			} else {
				//更新队列让他可以从新入队
				Db::name('mission')->where('mission_id', $mission['mission_id'])->update(['mission_queues' => 0]);
				$this->queueLog($payment['payment_controller'], $infoId, $plan['plan_form_no'] . 'MQ排队失败请联系技术');
				return json(array('error' => 1, 'msg' => 'MQ排队失败请联系技术', 'hid' => $infoId));
			}
		} else {
			return json(array('error' => 1, 'msg' => 'MQ排队失败请联系技术:' . $jobHandlerClassName . '不存在', 'hid' => $infoId));
		}

	}

	public function checkRedis($mission=[])
	{
		$queueName = "queues:jhqueues:delayed";
		$redis = $this->connectRedis();
		$list = $redis->zrange($queueName,0,-1);
		$res = false;
		if(empty($list)){
			return $res;
		}
		if(empty($mission)){
			return $list;
		}
		foreach ($list as $item) {
			$item = json_decode($item,true);
			if($mission["mission_id"] == $item["data"]["mission"]["mission_id"]){
				$res = true;
			}
		}
		return $res;
	}


	private function connectRedis()
	{
		$redis = new \Redis();
		$redis->connect("127.0.0.1", "6379");
		return $redis;
	}

	/**
	 * 队列记录
	 *
	 * @param $path
	 * @param $logId
	 * @param $msg
	 */
	protected function queueLog($path, $logId, $msg)
	{
		$pathnews = 'logs/';
		//创建类型
		if (!is_dir($pathnews)) {
			mkdir($pathnews, 0777, true);
		}
		$pathnews = 'logs/queueLog/';
		//创建类型
		if (!is_dir($pathnews)) {
			mkdir($pathnews, 0777, true);
		}
		$pathnews = $pathnews . $path;
		//创建类型
		if (!is_dir($pathnews)) {
			mkdir($pathnews, 0777, true);
		}
		$filename = $pathnews . '/' . $logId . '.txt';
		if($this->isCli()){
			$filename = $pathnews . '/' . $logId . '_cli.txt';
		}

		$content = date("Y-m-d H:i:s", time()) . "\r\n" . $msg . "\r\n \r\n \r\n ";
		file_put_contents($filename, $content, FILE_APPEND);
	}

	public function isCli(){
		return preg_match("/cli/i", php_sapi_name()) ? true : false;
	}


	/**
	 * 补单推送
	 * @return mixed
	 */
	public
	function bd()
	{
		$form_no = input('get.form_no');
		if (empty($form_no)) {
			return json(['error' => 1, 'msg' => '订单错误']);
		}

		$plan = Db::name('plan')->where('plan_form_no', $form_no)->where('plan_state', 2)->find();
		if (empty($plan)) {
			return json(['error' => 1, 'msg' => '该订单无需补单']);
		}

		Db::name('plan')->where('plan_form_no', $form_no)->update(['plan_state' => 0, 'plan_form_no' => $form_no . 'BD']);
		Db::name('mission')->where('mission_id', $plan['plan_mid'])->update(['mission_type' => 0, 'mission_queues' => 0]);
		return json(['error' => 0, 'msg' => '成功']);
	}
}
